﻿using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Traceability.Commont.Infrastructures.Interfaces;

namespace Traceability.Commont.DBContexts
{
    /// <summary>
    /// 上下文的基类
    /// </summary>
    public class BaseDBContext : DbContext
    {
        private readonly IMediator mediator;

        public BaseDBContext(IMediator mediator, DbContextOptions options) : base(options)
        {
            this.mediator = mediator;
        }

        public override int SaveChanges(bool acceptAllChangesOnSucess)
        {
            //在项目中强制要求不能使用同步方法，因此对SaveChanges的调用抛出异常。
            throw new NotImplementedException("未调用SaveChanges");
        }


        public async override Task<int> SaveChangesAsync(bool acceptAllChangesOnSucess,CancellationToken cancellationToken=default)
        {
            //ChangeTracker是上下文中用来对实体类的变化进行追踪的对象，
            //Entries<IDomainEvents>获得的是所有实现了IDomainEvents接口的追踪实体类
            var domainEntites = this.ChangeTracker.Entries<IDomainEvent>()
                .Where(x => x.Entity.GetDoaminEvents().Any());
            //获取上边多个或单个实体类里的 领域事件
            var domianEvents = domainEntites.SelectMany(x => x.Entity.GetDoaminEvents()).ToList();

            domainEntites.ToList().ForEach(entity => entity.Entity.ClearDomainEvents());
            // 在调用父类的SaveChangesAsync方法保存修改之前，
            //我们把所有实体类中注册的领域事件发布出去

            foreach (var domainEvent in domianEvents)
            {
                await mediator.Publish(domainEvent);
            }
            return await base.SaveChangesAsync(acceptAllChangesOnSucess, cancellationToken);
        }
    }
}
